import re


def name_convert_to_camel(name: str) -> str:
    """
    下划线转驼峰(小驼峰)
    """
    return re.sub(r'(_[a-z])', lambda x: x.group(1)[1].upper(), name)


def name_convert_to_snake(name: str) -> str:
    """
    驼峰转下划线
    """
    if '_' not in name:
        name = re.sub(r'([a-z])([A-Z])', r'\1_\2', name)
    else:
        raise ValueError(f'{name}字符中包含下划线，无法转换')
    return name.lower()


def name_convert(name: str) -> str:
    """
    小驼峰式命名和下划线式命名互转
    """
    is_camel_name = True  # 是否为驼峰式命名
    if '_' in name and re.match(r'[a-zA-Z_]+$', name):
        is_camel_name = False
    elif re.match(r'[a-zA-Z]+$', name) is None:
        raise ValueError(f'Value of "name" is invalid: {name}')
    return name_convert_to_snake(name) if is_camel_name else name_convert_to_camel(name)


def dict_key_convert_to_camel(dict_obj: dict, null=False, safe: list = None, delete: list = None):
    """
    将dict的key转换为小驼峰
    参数：
        dict_obj：需要转换的字典
        null：默认为False
            True：删除字典中的None值和空值
            False：不删除
        safe：
            数据类型：列表
            数据参数：不需要清除的原字典中的key
            数据有效性：在null为True的时候有效
        delete：
            数据类型：列表
            数据参数：需要删除的原字典中的key
    """
    try:
        # 返回对象
        if safe is None:
            safe = []
        result_dict = dict()

        # 遍历字典对象
        dict_items = dict_obj.items()
        # 储存需要删除的key
        del_key = []

        for key, value in dict_items:
            # 将key值转换为小驼峰
            key_camel = name_convert_to_camel(key)

            # null为True，删除字典中的None值和空值
            if null is True:
                # 当key在safe标签时，不清除safe
                if key in safe:
                    pass
                elif value is None or value == '':
                    del_key.append(key_camel)

            # 如果value为字典，递归调用
            if isinstance(value, dict):
                value = dict_key_convert_to_camel(value, null=null, safe=safe, delete=delete)

            # 如果value为列表，遍历递归调用
            if isinstance(value, list):
                for i in range(len(value)):
                    value[i] = dict_key_convert_to_camel(value[i], null=null, safe=safe, delete=delete)

            if delete is None or key not in delete:
                result_dict[key_camel] = value

        # 删除需要清除的None值和空值
        if null is True:
            for key in del_key:
                del result_dict[key]

        return result_dict
    except AttributeError:
        return dict_obj
